﻿using Carer.Data.Cache;
using Carer.Data.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Linq;
using System.Linq.Expressions;
using Carer.Data.Enum;
using NLog;

namespace Carer.Data
{
    public class DataService
    {
        private static Logger _logger = LogManager.GetLogger("DataService");


        private static Func<IGrouping<DateTime?, Schedule>, Schedule[]> func_31;


        private static Func<IGrouping<DateTime?, Schedule>, Schedule[]> func_33;

        private static Func<Schedule, Schedule> func_34;

        public DataService()
        {

        }

        public static bool AddSchedule(Schedule s, long[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (!s.CreateTime.HasValue)
                {
                    s.CreateTime = DateTime.Now;
                }
                double num = (s.Shift == 0) ? 1.0 : 0.5;
                if (s.IsHoliday == true)
                {
                    num *= 2.0;
                }
                double num2 = s.Adjust.HasValue ? s.Adjust.Value : 0.0;
                foreach (long id in ids)
                {
                    Order order = (from i in entities.Orders.Include("Service")
                                   where i.Id == id
                                   select i).FirstOrDefault<Order>();
                    if ((order != null) && (order.Service != null))
                    {
                        Schedule entity = new Schedule
                        {
                            CrewId = s.CrewId,
                            Start = s.Start,
                            End = s.End,
                            OrderId = new long?(id),
                            IsHoliday = s.IsHoliday,
                            Shift = s.Shift,
                            PaymentId = s.PaymentId,
                            Ratio = s.Ratio,
                            Adjust = s.Adjust,
                            Operator = s.Operator
                        };
                        entity.Pay = new double?(((order.Service.Price * entity.Ratio.Value) * num) + num2);
                        entities.Schedules.Add(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool CheckCustomer(Customer c, out string msg)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (!string.IsNullOrEmpty(c.IdNo) && ((from i in entities.Customers
                                                       where (i.Id != c.Id) && (i.IdNo == c.IdNo)
                                                       select i).FirstOrDefault<Customer>() != null))
                {
                    msg = "具有该身份证的客户已经存在";
                    return false;
                }

                //姓名可以重复
                //姓名+电话不能重复,电话为空不判断
                if (!string.IsNullOrEmpty(c.Name) && !string.IsNullOrEmpty(c.Tel))
                {
                    bool flag = true;
                    msg = string.Empty;
                    if (c.Id == 0)//新增
                    {
                        flag = !entities.Customers.Where(it => it.Tel == c.Tel).Any();
                    }
                    else //修改
                    {
                        flag = !entities.Customers.Where(it => it.Id != c.Id && it.Tel == c.Tel).Any();
                    }

                    if (!flag)
                    {
                        msg = "具有该电话号码的客户已经存在";
                    }
                    return flag;
                }
                msg = string.Empty;
                return true;
            }
        }

        public static User CheckUser(string name, string pass)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Users.Include("Unit")
                        where (i.Name == name) && (i.Password == pass)
                        select i).FirstOrDefault<User>();
            }
        }

        public static bool DeleteBonus(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Bonus entity = (from i in entities.Bonuses
                                where i.Id == id
                                select i).FirstOrDefault<Bonus>();
                if (entity != null)
                {
                    entities.Bonuses.Remove(entity);
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteBonus(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    Bonus entity = (from i in entities.Bonuses
                                    where i.Id == id
                                    select i).FirstOrDefault<Bonus>();
                    if (entity != null)
                    {
                        entities.Bonuses.Remove(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteCategory(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Category entity = (from i in entities.Categories
                                   where i.Id == id
                                   select i).FirstOrDefault<Category>();
                if (entity != null)
                {
                    entities.Categories.Remove(entity);
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteCategory(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    Category entity = (from i in entities.Categories
                                       where i.Id == id
                                       select i).FirstOrDefault<Category>();
                    if (entity != null)
                    {
                        entities.Categories.Remove(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteCrew(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Schedule schedule = (from i in entities.Schedules
                                     where i.CrewId == id
                                     select i).FirstOrDefault<Schedule>();
                //有排班不允许删除
                if (schedule == null)
                {
                    Crew entity = (from i in entities.Crews
                                   where i.Id == id
                                   select i).FirstOrDefault<Crew>();
                    if (entity != null)
                    {
                        entities.Crews.Remove(entity);
                    }
                    return SaveChanges(entities);
                }

                return false;
            }
        }

        public static bool DeleteCrew(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    Schedule schedule = (from i in entities.Schedules
                                         where i.CrewId == id
                                         select i).FirstOrDefault<Schedule>();
                    //有排班不允许删除
                    if (schedule == null)
                    {
                        Crew entity = (from i in entities.Crews
                                       where i.Id == id
                                       select i).FirstOrDefault<Crew>();
                        if (entity != null)
                        {
                            entities.Crews.Remove(entity);
                        }
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteCrewType(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                CrewType entity = (from i in entities.CrewTypes
                                   where i.Id == id
                                   select i).FirstOrDefault<CrewType>();
                if (entity != null)
                {
                    entities.CrewTypes.Remove(entity);
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteCrewType(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    CrewType entity = (from i in entities.CrewTypes
                                       where i.Id == id
                                       select i).FirstOrDefault<CrewType>();
                    if (entity != null)
                    {
                        entities.CrewTypes.Remove(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteCustomer(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Order order = (from i in entities.Orders
                               where i.CustomerId == id
                               select i).FirstOrDefault<Order>();
                if (order == null)
                {
                    Customer entity = (from i in entities.Customers
                                       where i.Id == id
                                       select i).FirstOrDefault<Customer>();
                    if (entity != null)
                    {
                        entities.Customers.Remove(entity);
                    }
                    return SaveChanges(entities);
                }

                return false;
            }
        }

        public static bool DeleteCustomer(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    Order order = (from i in entities.Orders
                                   where i.CustomerId == id
                                   select i).FirstOrDefault<Order>();
                    //有订单就不能删除
                    if (order == null)
                    {
                        Customer entity = (from i in entities.Customers
                                           where i.Id == id
                                           select i).FirstOrDefault<Customer>();
                        if (entity != null)
                        {
                            entities.Customers.Remove(entity);
                        }
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteOrder(long id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Schedule schedule = (from i in entities.Schedules
                                     where i.OrderId == id
                                     select i).FirstOrDefault<Schedule>();
                //有排班了不能删除
                if (schedule == null)
                {
                    Order entity = (from i in entities.Orders
                                    where i.Id == id
                                    select i).FirstOrDefault<Order>();
                    if (entity != null)
                    {
                        entities.Orders.Remove(entity);
                    }
                    return SaveChanges(entities);
                }

                return false;
            }
        }

        public static bool DeleteOrder(long[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (long id in ids)
                {
                    Schedule schedule = (from i in entities.Schedules
                                         where i.OrderId == id
                                         select i).FirstOrDefault<Schedule>();
                    //有排班了不能删除
                    if (schedule == null)
                    {
                        Order entity = (from i in entities.Orders
                                        where i.Id == id
                                        select i).FirstOrDefault<Order>();
                        if (entity != null)
                        {
                            entities.Orders.Remove(entity);
                        }
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeletePayment(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Payment entity = (from i in entities.Payments
                                  where i.Id == id
                                  select i).FirstOrDefault<Payment>();
                if (entity != null)
                {
                    entities.Payments.Remove(entity);
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeletePayment(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    Payment entity = (from i in entities.Payments
                                      where i.Id == id
                                      select i).FirstOrDefault<Payment>();
                    if (entity != null)
                    {
                        entities.Payments.Remove(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteSchedule(long id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Schedule entity = (from i in entities.Schedules
                                   where i.Id == id
                                   select i).FirstOrDefault<Schedule>();
                if (entity != null)
                {
                    entities.Schedules.Remove(entity);
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteSchedule(long[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (long id in ids)
                {
                    Schedule entity = (from i in entities.Schedules
                                       where i.Id == id
                                       select i).FirstOrDefault<Schedule>();
                    if (entity != null)
                    {
                        entities.Schedules.Remove(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteService(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Service entity = (from i in entities.Services
                                  where i.Id == id
                                  select i).FirstOrDefault<Service>();
                if (entity != null)
                {
                    entities.Services.Remove(entity);
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteService(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    Service entity = (from i in entities.Services
                                      where i.Id == id
                                      select i).FirstOrDefault<Service>();
                    if (entity != null)
                    {
                        entities.Services.Remove(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteUnit(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    Unit entity = (from i in entities.Units
                                   where i.Id == id
                                   select i).FirstOrDefault<Unit>();
                    if (entity != null)
                    {
                        entities.Units.Remove(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteUser(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                User entity = (from i in entities.Users
                               where i.Id == id
                               select i).FirstOrDefault<User>();
                if (entity != null)
                {
                    entities.Users.Remove(entity);
                }
                return SaveChanges(entities);
            }
        }

        public static bool DeleteUser(int[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (int id in ids)
                {
                    User entity = (from i in entities.Users
                                   where i.Id == id
                                   select i).FirstOrDefault<User>();
                    if (entity != null)
                    {
                        entities.Users.Remove(entity);
                    }
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditBonus(Bonus u)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (u.Id == 0)
                {
                    entities.Bonuses.Add(u);
                }
                else
                {
                    Bonus bonus = (from i in entities.Bonuses
                                   where i.Id == u.Id
                                   select i).FirstOrDefault<Bonus>();
                    if (bonus == null)
                    {
                        return false;
                    }
                    bonus.CrewId = u.CrewId;
                    bonus.Date = u.Date;
                    bonus.Item = u.Item;
                    bonus.Value = u.Value;
                    bonus.Note = u.Note;
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditCategory(Category u)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (u.Id == 0)
                {
                    entities.Categories.Add(u);
                }
                else
                {
                    Category category = (from i in entities.Categories
                                         where i.Id == u.Id
                                         select i).FirstOrDefault<Category>();
                    if (category == null)
                    {
                        return false;
                    }
                    category.Name = u.Name;
                    category.Prefix = u.Prefix;
                    category.Order = u.Order;
                    category.UnitId = u.UnitId;
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditCrew(Crew c, out string msg)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                Crew crew = (from i in entities.Crews.Include("OwnerUnit")
                             where (i.Id != c.Id) && (i.Name == c.Name)
                             select i).FirstOrDefault<Crew>();
                if (crew != null)
                {

                    msg = String.Format("具有该姓名的人员在{0}已存在", (crew.OwnerUnitId != null) ? crew.OwnerUnit.Name : "平台");
                    return false;
                }
                crew = (from i in entities.Crews.Include("OwnerUnit")
                        where (i.Id != c.Id) && (i.IdNo == c.IdNo)
                        select i).FirstOrDefault<Crew>();
                if (crew != null)
                {
                    msg = String.Format("具有该身份证号的人员在{0}已存在", (crew.OwnerUnit != null) ? crew.OwnerUnit.Name : "平台");
                    return false;
                }
                if (c.Id == 0)
                {
                    entities.Crews.Add(c);
                }
                else
                {
                    Crew crew2 = (from i in entities.Crews
                                  where i.Id == c.Id
                                  select i).FirstOrDefault<Crew>();
                    if (crew2 == null)
                    {
                        msg = "人员记录不存在或已被删除";
                        return false;
                    }
                    crew2.Name = c.Name;
                    crew2.Gender = c.Gender;
                    crew2.Skill = c.Skill;
                    crew2.Type = c.Type;
                    crew2.Status = c.Status;
                    crew2.WorkStart = c.WorkStart;
                    crew2.WorkEnd = c.WorkEnd;
                    crew2.IdNo = c.IdNo;
                    crew2.IdIssuer = c.IdIssuer;
                    crew2.IdStart = c.IdStart;
                    crew2.IdEnd = c.IdEnd;
                    crew2.TrcNo = c.TrcNo;
                    crew2.TrcIssue = c.TrcIssue;
                    crew2.TrcStart = c.TrcStart;
                    crew2.Birthday = c.Birthday;
                    crew2.Native = c.Native;
                    crew2.Addr = c.Addr;
                    crew2.Tel = c.Tel;
                    crew2.Level = c.Level;
                    crew2.HealthNo = c.HealthNo;
                    crew2.HealthIssuer = c.HealthIssuer;
                    crew2.HealthStart = c.HealthStart;
                    crew2.LicenseNo = c.LicenseNo;
                    crew2.LicenseType = c.LicenseType;
                    crew2.LicenseIssuer = c.LicenseIssuer;
                    crew2.LicenseStart = c.LicenseStart;
                    crew2.Training = c.Training;
                    if (c.Photo != null)
                    {
                        crew2.PhotoType = c.PhotoType;
                        crew2.Photo = c.Photo;
                    }
                    crew2.Note = c.Note;
                    crew2.OwnerUnitId = c.OwnerUnitId;
                    crew2.ServiceUnitId = c.ServiceUnitId;
                    crew2.PaymentId = c.PaymentId;
                }
                bool flag2 = SaveChanges(entities);
                msg = flag2 ? "人员记录保存成功" : "人员记录保存失败";
                return flag2;
            }
        }

        public static bool EditCrewType(CrewType u)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (u.Id == 0)
                {
                    entities.CrewTypes.Add(u);
                }
                else
                {
                    CrewType type = (from i in entities.CrewTypes
                                     where i.Id == u.Id
                                     select i).FirstOrDefault<CrewType>();
                    if (type == null)
                    {
                        return false;
                    }
                    type.Name = u.Name;
                    type.Ratio = u.Ratio;
                    type.Order = u.Order;
                    type.UnitId = u.UnitId;
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditCustomer(Customer u)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (u.Id == 0)
                {
                    entities.Customers.Add(u);
                }
                else
                {
                    Customer customer = (from i in entities.Customers
                                         where i.Id == u.Id
                                         select i).FirstOrDefault<Customer>();
                    if (customer == null)
                    {
                        return false;
                    }
                    customer.Name = u.Name;
                    customer.Tel = u.Tel;
                    customer.Gender = u.Gender;
                    customer.Birthday = u.Birthday;
                    customer.IdNo = u.IdNo;
                    customer.Addr = u.Addr;
                    customer.BabyGender = u.BabyGender;
                    customer.BabyBirth = u.BabyBirth;
                    customer.BabyWeight = u.BabyWeight;
                    customer.Contact = u.Contact;
                    customer.ContactTel = u.ContactTel;
                    customer.ContactRel = u.ContactRel;
                    customer.Note = u.Note;
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditOrder(Order u)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (!u.CreateTime.HasValue)
                {
                    u.CreateTime = DateTime.Now;
                }

                if (u.Id == 0L)
                {
                    entities.Orders.Add(u);
                }
                else
                {
                    Order order = (from i in entities.Orders
                                   where i.Id == u.Id
                                   select i).FirstOrDefault<Order>();
                    if (order == null)
                    {
                        return false;
                    }
                    order.ServiceId = u.ServiceId;
                    order.CustomerId = u.CustomerId;
                    order.State = u.State;
                    order.Shift = u.Shift;
                    order.Area = u.Area;
                    order.Bed = u.Bed;
                    order.Addr = u.Addr;
                    order.Company = u.Company;
                    order.Start = u.Start;
                    order.End = u.End;
                    order.Num = u.Num;
                    order.Holidays = u.Holidays;
                    order.Discount = u.Discount;
                    order.Adjust = u.Adjust;
                    order.Charge = u.Charge;
                    order.Invoice = u.Invoice;
                    order.ReceiptType = u.ReceiptType;
                    order.ReceiptNo = u.ReceiptNo;
                    order.BillSigner = u.BillSigner;
                    order.Receiver = u.Receiver;
                    order.Prepay = u.Prepay;
                    order.Note = u.Note;
                    order.UnitId = u.UnitId;
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditPayment(Payment u)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (u.Id == 0)
                {
                    entities.Payments.Add(u);
                }
                else
                {
                    Payment payment = (from i in entities.Payments
                                       where i.Id == u.Id
                                       select i).FirstOrDefault<Payment>();
                    if (payment == null)
                    {
                        return false;
                    }
                    payment.Name = u.Name;
                    payment.Ratio = u.Ratio;
                    payment.UnitId = u.UnitId;
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditSchedule(Schedule s, out string msg)
        {
            if (!(s.OrderId.HasValue && s.CrewId.HasValue))
            {
                msg = "未选择订单或者服务人员";
                return false;
            }
            using (CarerEntities entities = new CarerEntities())
            {
                Order order = (from i in entities.Orders
                               where i.Id == s.OrderId
                               select i).FirstOrDefault<Order>();
                if (order == null)
                {
                    msg = "与该排班相关的订单不存在";
                    return false;
                }
                if (!s.Start.HasValue)
                {
                    msg = "服务时间不能为空";
                    return false;
                }
                if (!s.End.HasValue)
                {
                    msg = "结束时间不能为空";
                    return false;
                }
                if (!s.Shift.HasValue)
                {
                    msg = "没有设置班次信息";
                    return false;
                }
                DateTime? start = s.Start;
                DateTime? orderStart = order.Start;
                if (((start.HasValue & orderStart.HasValue) ? (start.GetValueOrDefault() < orderStart.GetValueOrDefault()) : false) || (((start = s.End).HasValue & (orderStart = order.End).HasValue) ? (start.GetValueOrDefault() > orderStart.GetValueOrDefault()) : false))
                {
                    msg = "排班时间与当前订单时间冲突";
                    return false;
                }


                if (!s.CreateTime.HasValue)
                {
                    s.CreateTime = DateTime.Now;
                }


                var checkResult = CheckSchedule(s, new long[] { s.OrderId.HasValue ? s.OrderId.Value : 0L });
                if (!checkResult.Item1)
                {
                    msg = checkResult.Item2;
                    return false;
                }


                if (s.Id == 0L)
                {
                    entities.Schedules.Add(s);
                }
                else
                {
                    Schedule schedule = (from i in entities.Schedules
                                         where i.Id == s.Id
                                         select i).FirstOrDefault<Schedule>();
                    if (schedule == null)
                    {
                        msg = "原排班信息不存在或者已经被删除";
                        return false;
                    }
                    schedule.CrewId = s.CrewId;
                    schedule.OrderId = s.OrderId;
                    schedule.Start = s.Start;
                    schedule.End = s.End;
                    schedule.IsHoliday = s.IsHoliday;
                    schedule.Shift = s.Shift;
                    schedule.PaymentId = s.PaymentId;
                    schedule.Ratio = s.Ratio;
                    schedule.Adjust = s.Adjust;
                    schedule.Rate = s.Rate;
                    schedule.Pay = s.Pay;
                    schedule.Operator = s.Operator;
                    schedule.Note = s.Note;
                }


                bool flag2 = SaveChanges(entities);
                msg = flag2 ? "排班信息保存成功" : "排班信息保存失败";
                return flag2;
            }
        }

        public static bool EditService(Service u)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (u.Id == 0)
                {
                    entities.Services.Add(u);
                }
                else
                {
                    Service service = (from i in entities.Services
                                       where i.Id == u.Id
                                       select i).FirstOrDefault<Service>();
                    if (service == null)
                    {
                        return false;
                    }
                    service.Name = u.Name;
                    service.Type = u.Type;
                    service.Unit = u.Unit;
                    service.Price = u.Price;
                    service.UnitId = u.UnitId;
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditUnit(Unit h)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (h.Id == 0)
                {
                    entities.Units.Add(h);
                }
                else
                {
                    Unit unit = (from i in entities.Units
                                 where i.Id == h.Id
                                 select i).FirstOrDefault<Unit>();
                    if (unit == null)
                    {
                        return false;
                    }
                    unit.Name = h.Name;
                    unit.Kind = h.Kind;
                    unit.Addr = h.Addr;
                    unit.Order = h.Order;
                    unit.Company = h.Company;
                }
                return SaveChanges(entities);
            }
        }

        public static bool EditUser(User u)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                if (u.Id == 0)
                {
                    entities.Users.Add(u);
                }
                else
                {
                    User user = (from i in entities.Users
                                 where i.Id == u.Id
                                 select i).FirstOrDefault<User>();
                    if (user == null)
                    {
                        return false;
                    }
                    user.Name = u.Name;
                    user.Password = u.Password;
                    user.Role = u.Role;
                    user.Revoke = u.Revoke;
                    user.Remark = u.Remark;
                    user.UnitId = u.UnitId;
                }
                return SaveChanges(entities);
            }
        }

        public static IList<Bonus> FilterBonuses(BonusQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Bonus> source = from i in entities.Bonuses.Include("Crew") select i;
                if (!string.IsNullOrEmpty(q.CrewName))
                {
                    source = from i in source
                             where i.Crew.Name.Contains(q.CrewName)
                             select i;
                }
                if (q.Start.HasValue)
                {
                    source = from i in source
                             where i.Date > q.Start
                             select i;
                }
                if (q.End.HasValue)
                {
                    source = from i in source
                             where i.Date <= q.End
                             select i;
                }
                return source.ToArray<Bonus>();
            }
        }

        public static IList<Category> FilterCategories(CategoryQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Category> source = from c in entities.Categories
                                              where c.UnitId == q.UnitId
                                              select c;
                if (!string.IsNullOrEmpty(q.Name))
                {
                    source = from i in source
                             where i.Name.Contains(q.Name)
                             select i;
                }
                return source.ToArray<Category>();
            }
        }

        public static IQueryable<Crew> FilterCrews(CarerEntities ctx, CrewQuery q)
        {
            IQueryable<Crew> queryable = from c in ctx.Crews.Include("OwnerUnit").Include("ServiceUnit") select c;
            if (!string.IsNullOrEmpty(q.Name))
            {
                queryable = from i in queryable
                            where i.Name == q.Name || i.Name.Contains(q.Name)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Skill))
            {
                queryable = from i in queryable
                            where i.Skill.Contains(q.Skill)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Status))
            {
                queryable = from i in queryable
                            where i.Status.Contains(q.Status)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Type))
            {
                queryable = from i in queryable
                            where i.Type.Contains(q.Type)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.IdNo))
            {
                queryable = from i in queryable
                            where i.IdNo.Equals(q.IdNo) || i.IdNo.Contains(q.IdNo)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Gender))
            {
                queryable = from i in queryable
                            where i.Gender.Equals(q.Gender)
                            select i;
            }
            if (q.Birthday.HasValue)
            {
                queryable = from i in queryable
                            where i.Birthday == q.Birthday
                            select i;
            }
            if (q.WorkStart.HasValue)
            {
                queryable = from i in queryable
                            where i.WorkStart == q.WorkStart
                            select i;
            }

            int? unitId = q.UnitId;
            if (unitId.HasValue)
            {
                unitId = null;
                queryable = from i in queryable
                            where (((i.OwnerUnitId == q.UnitId) || (i.OwnerUnitId == unitId)) || (i.ServiceUnitId == q.UnitId)) || (i.ServiceUnitId == null)
                            select i;
            }
            return queryable;
        }

        public static IList<CrewType> FilterCrewTypes(CrewTypeQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<CrewType> source = from c in entities.CrewTypes
                                              where c.UnitId == q.UnitId
                                              select c;
                if (!string.IsNullOrEmpty(q.Name))
                {
                    source = from i in source
                             where i.Name.Contains(q.Name)
                             select i;
                }
                return source.ToArray<CrewType>();
            }
        }

        public static IQueryable<Customer> FilterCustomers(CarerEntities ctx, CustomerQuery q)
        {
            IQueryable<Customer> queryable = from i in ctx.Customers select i;
            if (!string.IsNullOrEmpty(q.Name))
            {
                queryable = from i in queryable
                            where i.Name == q.Name || i.Name.Contains(q.Name)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.IdNo))
            {
                queryable = from i in queryable
                            where i.IdNo == q.IdNo || i.IdNo.Contains(q.IdNo)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Tel))
            {
                queryable = from i in queryable
                            where i.Tel == q.Tel || i.Tel.Contains(q.Tel)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Contact))
            {
                queryable = from i in queryable
                            where i.Contact == q.Contact || i.Contact.Contains(q.Contact)
                            select i;
            }
            return queryable;
        }

        public static IEnumerable<Order> FilterOrders(CarerEntities ctx, OrderQuery q)
        {
            IQueryable<Order> queryable = from i in ctx.Orders.Include("Customer").Include("Service").Include("Unit")
                                          where i.UnitId == q.UnitId
                                          select i;
            if (!string.IsNullOrEmpty(q.CustomerName))
            {
                queryable = from i in queryable
                            where i.Customer.Name.Contains(q.CustomerName)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Category))
            {
                queryable = from i in queryable
                            where i.Service.Type == q.Category
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Area))
            {
                queryable = from i in queryable
                            where i.Area == q.Area
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Bed))
            {
                queryable = from i in queryable
                            where i.Bed == q.Bed
                            select i;
            }
            if (q.From.HasValue)
            {
                queryable = from i in queryable
                            where i.Start > q.From.Value
                            select i;
            }
            if (q.To.HasValue)
            {
                DateTime end = q.To.Value.AddDays(1.0);
                queryable = from i in queryable
                            where i.Start <= end
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Invoice))
            {
                queryable = from i in queryable
                            where i.Invoice.Contains(q.Invoice)
                            select i;
            }
            if (q.State.HasValue)
            {
                queryable = from i in queryable
                            where i.State == q.State.Value
                            select i;
            }

            //查询
            var orders = queryable.ToList();
            var orderIds = queryable.Select(it => it.Id).ToList();
            var schedules = ctx.Schedules.Where(it => (it.OrderId.HasValue && orderIds.Contains(it.OrderId.Value))).ToList();
            foreach (var order in orders)
            {
                order.Schedules = schedules.Where(it => it.OrderId.HasValue && it.OrderId.Value == order.Id).ToList();
            }

            return orders;
        }

        public static IList<Order> FilterOrders(CarerEntities ctx, RevenueQuery q)
        {
            IQueryable<Order> queryable = from i in ctx.Orders.Include("Customer").Include("Service")
                                          where i.UnitId == q.UnitId
                                          select i;
            if (q.Start.HasValue)
            {
                queryable = from i in queryable
                            where i.Start >= q.Start
                            select i;
            }
            if (q.End.HasValue)
            {
                DateTime end = q.End.Value.AddDays(1.0);
                queryable = from i in queryable
                            where i.End <= end
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Company))
            {
                queryable = from i in queryable
                            where i.Company == q.Company
                            select i;
            }
            if (!string.IsNullOrEmpty(q.CustomerName))
            {
                queryable = from i in queryable
                            where i.Customer.Name == q.CustomerName
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Category))
            {
                queryable = from i in queryable
                            where i.Service.Type == q.Category
                            select i;
            }
            if (!string.IsNullOrEmpty(q.ReceiptType))
            {
                queryable = from i in queryable
                            where i.ReceiptType == q.ReceiptType
                            select i;
            }
            if (!string.IsNullOrEmpty(q.ReceiptNo))
            {
                queryable = from i in queryable
                            where i.ReceiptNo.Contains(q.ReceiptNo)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Area))
            {
                queryable = from i in queryable
                            where i.Area == q.Area
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Bed))
            {
                queryable = from i in queryable
                            where i.Bed == q.Bed
                            select i;
            }
            if (!string.IsNullOrEmpty(q.BillSigner))
            {
                queryable = from i in queryable
                            where i.BillSigner.Contains(q.BillSigner)
                            select i;
            }
            if (q.State.HasValue)
            {
                queryable = from i in queryable
                            where i.State == q.State
                            select i;
            }
            if (q.OnlySettle == OnlySettle.Settled)
            {
                queryable = from i in queryable
                            where (i.Start.HasValue && i.End.HasValue && i.End.Value > i.Start.Value)
                            select i;
            }
            else if (q.OnlySettle == OnlySettle.Settling)
            {
                queryable = from i in queryable
                            where (i.Start.HasValue && !i.End.HasValue)
                            select i;
            }

            var orders = queryable.ToList();
            var orderIds = orders.Select(it => it.Id).ToList();
            var schedules = ctx.Schedules.Where(it => it.OrderId.HasValue && orderIds.Contains(it.OrderId.Value)).ToList();
            foreach (var order in orders)
            {
                order.Schedules = schedules.Where(it => it.OrderId.HasValue && it.OrderId.Value == order.Id).ToList();
            }

            return orders;
        }

        public static IList<Payment> FilterPayments(PaymentQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Payment> source = from p in entities.Payments
                                             where p.UnitId == q.UnitId
                                             select p;
                if (!string.IsNullOrEmpty(q.Name))
                {
                    source = from i in source
                             where i.Name.Contains(q.Name)
                             select i;
                }
                return source.ToArray<Payment>();
            }
        }

        public static IQueryable<Schedule> FilterSchedules(CarerEntities ctx, PayQuery q)
        {
            IQueryable<Order> queryable = from o in ctx.Orders.Include("Crew").Include("Customer").Include("Service")
                                          where (o.UnitId == q.UnitId) && (o.State == 0x100)
                                          select o;
            if (q.Start.HasValue)
            {
                queryable = from o in queryable
                            where o.Start >= q.Start
                            select o;
            }
            if (q.End.HasValue)
            {
                DateTime end = q.End.Value.AddDays(1.0);
                queryable = from o in queryable
                            where o.End <= end
                            select o;
            }
            if (!string.IsNullOrEmpty(q.Company))
            {
                queryable = from o in queryable
                            where o.Company == q.Company
                            select o;
            }
            if (!string.IsNullOrEmpty(q.CustomerName))
            {
                queryable = from o in queryable
                            where o.Customer.Name == q.CustomerName
                            select o;
            }
            if (!string.IsNullOrEmpty(q.Category))
            {
                queryable = from o in queryable
                            where o.Service.Type == q.Category
                            select o;
            }
            if (!string.IsNullOrEmpty(q.ReceiptType))
            {
                queryable = from o in queryable
                            where o.ReceiptType == q.ReceiptType
                            select o;
            }
            if (q.OnlySettle == OnlySettle.Settled)
            {
                queryable = from o in queryable
                            where (o.Start.HasValue && o.End.HasValue && o.End.Value > o.Start.Value)
                            select o;
            }
            else if (q.OnlySettle == OnlySettle.Settling)
            {
                queryable = from o in queryable
                            where (o.Start.HasValue && !o.End.HasValue)
                            select o;
            }

            var orderIds = queryable.Select(it => it.Id).ToList();

            IQueryable<Schedule> queryable2 = from o in ctx.Schedules
                                              where (o.OrderId.HasValue && orderIds.Contains(o.OrderId.Value))
                                              select o;

            if ((q.Shift > -1) && (q.Shift < 3))
            {
                queryable2 = from i in queryable2
                             where i.Shift == q.Shift
                             select i;
            }
            if (!string.IsNullOrEmpty(q.CrewName))
            {
                queryable2 = from i in queryable2
                             where i.Crew.Name.Contains(q.CrewName)
                             select i;
            }
            if (!string.IsNullOrEmpty(q.CrewType))
            {
                queryable2 = from i in queryable2
                             where i.Crew.Type == q.CrewType
                             select i;
            }
            return queryable2;
        }

        public static IQueryable<Schedule> FilterSchedules(CarerEntities ctx, ScheduleQuery q)
        {
            IQueryable<Schedule> queryable = from i in ctx.Schedules.Include("Order.Customer").Include("Order.Service").Include("Crew")
                                             where i.Order.UnitId == q.UnitId
                                             select i;
            if (q.CrewId != 0)
            {
                queryable = from i in queryable
                            where i.CrewId == q.CrewId
                            select i;
            }
            if (q.PaymentId.HasValue)
            {
                queryable = from i in queryable
                            where i.PaymentId == q.PaymentId.Value
                            select i;
            }
            if (!string.IsNullOrEmpty(q.CrewName))
            {
                queryable = from i in queryable
                            where i.Crew.Name.Contains(q.CrewName)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.CustomerName))
            {
                queryable = from i in queryable
                            where i.Order.Customer.Name.Contains(q.CustomerName)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Area))
            {
                queryable = from i in queryable
                            where i.Order.Area == q.Area
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Category))
            {
                queryable = from i in queryable
                            where i.Order.Service.Type == q.Category
                            select i;
            }
            if (q.Start.HasValue)
            {
                queryable = from i in queryable
                            where i.Start >= q.Start.Value
                            select i;
            }
            if (q.End.HasValue)
            {
                DateTime end = q.End.Value.AddDays(1.0);
                queryable = from i in queryable
                            where i.End <= end
                            select i;
            }
            return queryable;
        }

        public static IQueryable<Schedule> FilterSchedules(CarerEntities ctx, WageQuery q)
        {
            IQueryable<Order> queryable = from o in ctx.Orders
                                          where (o.UnitId == q.UnitId) && (o.State == 0x100)
                                          select o;
            if (q.Start.HasValue)
            {
                queryable = from o in queryable
                            where o.Start > q.Start
                            select o;
            }
            if (q.End.HasValue)
            {
                queryable = from o in queryable
                            where o.End <= q.End
                            select o;
            }
            if (!string.IsNullOrEmpty(q.Company))
            {
                queryable = from o in queryable
                            where o.Company == q.Company
                            select o;
            }
            if (!string.IsNullOrEmpty(q.Category))
            {
                queryable = from o in queryable
                            where o.Service.Type == q.Category
                            select o;
            }
            if (q.OnlySettle == OnlySettle.Settled)
            {
                queryable = from o in queryable
                            where (o.Start.HasValue && o.End.HasValue && o.End.Value > o.Start.Value)
                            select o;
            }
            else if (q.OnlySettle == OnlySettle.Settling)
            {
                queryable = from o in queryable
                            where (o.Start.HasValue && !o.End.HasValue)
                            select o;
            }
            var orders = queryable.ToList();
            var orderIds = orders.Select(it => it.Id).ToList();

            IQueryable<Schedule> queryable2 = from o in ctx.Schedules
                                              where o.OrderId.HasValue && orderIds.Contains(o.OrderId.Value)
                                              select o;
            int? shift = q.Shift;
            if (((shift.GetValueOrDefault() > -1) && shift.HasValue) && (((shift = q.Shift).GetValueOrDefault() < 3) && shift.HasValue))
            {
                queryable2 = from i in queryable2
                             where i.Shift == q.Shift
                             select i;
            }
            if (!string.IsNullOrEmpty(q.CrewName))
            {
                queryable2 = from i in queryable2
                             where i.Crew.Name.Contains(q.CrewName)
                             select i;
            }
            if (!string.IsNullOrEmpty(q.CrewType))
            {
                queryable2 = from i in queryable2
                             where i.Crew.Type == q.CrewType
                             select i;
            }
            return queryable2;
        }

        public static IQueryable<Schedule> FilterSchedules(CarerEntities ctx, WorkQuery q)
        {
            IQueryable<Schedule> queryable = from i in ctx.Schedules.Include("Order.Customer").Include("Order.Service").Include("Crew")
                                             where i.Order.UnitId == q.UnitId
                                             select i;
            if (q.Start.HasValue)
            {
                queryable = from i in queryable
                            where i.Start > q.Start.Value
                            select i;
            }
            if (q.End.HasValue)
            {
                DateTime end = q.End.Value.AddDays(1.0);
                queryable = from i in queryable
                            where i.Start <= end
                            select i;
            }
            if ((q.Shift > -1) && (q.Shift < 3))
            {
                queryable = from i in queryable
                            where i.Shift == q.Shift
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Company))
            {
                queryable = from i in queryable
                            where i.Order.Company == q.Company
                            select i;
            }
            if (!string.IsNullOrEmpty(q.CrewName))
            {
                queryable = from i in queryable
                            where i.Crew.Name.Contains(q.CrewName)
                            select i;
            }
            if (!string.IsNullOrEmpty(q.CrewType))
            {
                queryable = from i in queryable
                            where i.Crew.Type == q.CrewType
                            select i;
            }
            if (!string.IsNullOrEmpty(q.Category))
            {
                queryable = from i in queryable
                            where i.Order.Service.Type == q.Category
                            select i;
            }
            if (!string.IsNullOrEmpty(q.ReceiptType))
            {
                queryable = from i in queryable
                            where i.Order.ReceiptType == q.ReceiptType
                            select i;
            }
            if (q.OnlySettle == OnlySettle.Settled)
            {
                queryable = from i in queryable
                            where (i.Order.Start.HasValue && i.Order.End.HasValue && i.Order.End.Value > i.Order.Start.Value)
                            select i;
            }
            else if (q.OnlySettle == OnlySettle.Settling)
            {
                queryable = from i in queryable
                            where (i.Order.Start.HasValue && !i.Order.End.HasValue)
                            select i;
            }
            return queryable;
        }

        public static IList<Service> FilterServices(ServiceQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Service> source = (from s in entities.Services
                                              where s.UnitId == q.UnitId
                                              select s).AsQueryable<Service>();
                if (!string.IsNullOrEmpty(q.Name))
                {
                    source = from i in source
                             where i.Name.Contains(q.Name)
                             select i;
                }
                if (!string.IsNullOrEmpty(q.Type))
                {
                    source = from i in source
                             where i.Type == q.Type
                             select i;
                }
                return source.ToArray<Service>();
            }
        }

        public static IList<Unit> FilterUnits(UnitQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Unit> source = from u in entities.Units select u;
                if (!string.IsNullOrEmpty(q.Name))
                {
                    source = from d in source
                             where d.Name.Contains(q.Name)
                             select d;
                }
                return source.ToArray<Unit>();
            }
        }

        public static IList<User> FilterUsers(UserQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<User> source = from u in entities.Users.Include("Unit") select u;
                if (!string.IsNullOrEmpty(q.Name))
                {
                    source = from i in source
                             where i.Name.Contains(q.Name)
                             select i;
                }
                return source.ToArray<User>();
            }
        }

        public static IList<Category> GetAllCategories(int? hid)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from c in entities.Categories
                        where c.UnitId == hid
                        orderby c.Order
                        select c).ToList<Category>();
            }
        }

        public static IList<CrewType> GetAllCrewTypes(int? hid)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from c in entities.CrewTypes
                        where c.UnitId == hid
                        orderby c.Order
                        select c).ToList<CrewType>();
            }
        }

        public static IList<Payment> GetAllPayments(int? uid)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Payments
                        where i.UnitId == uid
                        select i).AsEnumerable<Payment>()
                        .Select<Payment, Payment>(it => it.Clone()).ToList<Payment>();
            }
        }

        public static IList<Service> GetAllServices(int? hid)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from s in entities.Services
                        where s.UnitId == hid
                        orderby s.Id
                        select s).ToArray<Service>();
            }
        }

        public static IList<Unit> GetAllUnits()
        {
            var allUnits = CacheManager.Get(CacheConst.All_Unit);
            if (allUnits != null)
            {
                var rtn = allUnits as IList<Unit>;
                if (rtn != null && rtn.Count > 0)
                {
                    return rtn;
                }
            }

            using (CarerEntities entities = new CarerEntities())
            {
                var rtn = (from u in entities.Units orderby u.Order select u).ToList<Unit>();
                CacheManager.Set(CacheConst.All_Unit, rtn, CacheManager.DAY_1);

                return rtn;
            }
        }

        public static IEnumerable<Order> GetAvailableOrder(int? unitId, AvailableOrderQuery query)
        {
            //TODO 查询条件待确定
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Order> source = from o in entities.Orders
                                           where o.State == 0 && o.UnitId == unitId
                                           select o;
                if (query.CrewId.HasValue)
                {
                    Crew crew = GetCrew(query.CrewId.Value);
                    source = source.Where(it => it.Service.Type == crew.Skill);
                }
                if (query.Shift.HasValue)
                {
                    source = from i in source
                             where i.Shift == query.Shift
                             select i;
                }
                if (query.Start.HasValue)
                {
                    DateTime e = query.End.HasValue ? query.End.Value : query.Start.Value.AddHours(12.0);
                    source = from i in source
                             where (i.Start <= query.Start) && (!i.End.HasValue || i.End.Value >= e)
                             select i;
                    e = query.End.HasValue ? query.End.Value : query.Start.Value.AddDays(1.0);
                    //针对客户 一天最多一个全班 或者白班+夜班
                    //当前客户1:没排班,2:一个白班,3:一个夜班
                    source = source.Where(order => !entities.Schedules.Any(schedule => schedule.OrderId == order.Id && schedule.Shift.HasValue && schedule.Shift.Value == 0 && schedule.Start.HasValue && schedule.Start.Value < e && schedule.End.HasValue && schedule.End.Value > query.Start.Value)
                        && entities.Schedules.Count(schedule => schedule.OrderId == order.Id && ((schedule.Shift.HasValue && schedule.Shift.Value == 1) || (schedule.Shift.HasValue && schedule.Shift.Value == 2)) && schedule.Start.HasValue && schedule.Start.Value < e && schedule.End.HasValue && schedule.End.Value > query.Start.Value) < 2);
                }
                if (!string.IsNullOrWhiteSpace(query.ServiceTypeName))
                {
                    source = source.Where(it => it.Service != null && it.Service.Name.Contains(query.ServiceTypeName.Trim()));
                }

                var result = (from i in source
                              orderby i.CreateTime descending, i.Area, i.Bed
                              select i).AsEnumerable<Order>()
                        .Select<Order, Order>((val) =>
                        {
                            if (val != null)
                            {
                                return val.Clone();
                            }
                            return null;
                        }).ToArray<Order>();

                return result;
            }
        }

        public static Bonus GetBonus(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Bonuses
                        where i.Id == id
                        select i).AsEnumerable<Bonus>().Select<Bonus, Bonus>(it => it.Clone()).FirstOrDefault<Bonus>();
            }
        }

        public static QueryResult<Bonus> GetBonuses(BonusQuery q)
        {
            IList<Bonus> source = FilterBonuses(q);
            int num = (source.Count<Bonus>() + 9) / 10;
            num = (num == 0) ? 1 : num;
            QueryResult<Bonus> result = new QueryResult<Bonus>
            {
                MaxRows = source.Count(),
                Page = q.PageNumber,
                Total = num
            };

            result.Items = source.OrderBy<Bonus, int>(it => it.Id)
                .Skip<Bonus>(((q.PageNumber - 1) * q.PageSize))
                .Take<Bonus>(q.PageSize)
                .Select<Bonus, Bonus>(it => it.Clone()).ToArray<Bonus>();
            return result;
        }

        public static QueryResult<Category> GetCategories(CategoryQuery q)
        {
            IList<Category> source = FilterCategories(q);
            int num = (source.Count<Category>() + 9) / 10;
            num = (num == 0) ? 1 : num;
            QueryResult<Category> result = new QueryResult<Category>
            {
                MaxRows = source.Count(),
                Page = q.PageNumber,
                Total = num
            };

            result.Items = source.OrderBy<Category, int?>(it => it.Order)
                .Skip<Category>(((q.PageNumber - 1) * q.PageSize))
                .Take<Category>(q.PageSize)
                .Select<Category, Category>(it => it.Clone()).ToArray<Category>();
            return result;
        }

        public static Category GetCategory(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Categories
                        where i.Id == id
                        select i).AsEnumerable<Category>()
                        .Select<Category, Category>(it => it.Clone()).FirstOrDefault<Category>();
            }
        }

        public static Crew GetCrew(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from c in entities.Crews
                        where c.Id == id
                        select c).AsEnumerable<Crew>()
                        .Select<Crew, Crew>(it => it.Clone()).FirstOrDefault<Crew>();
            }
        }

        public static QueryResult<Crew> GetCrews(CrewQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Crew> source = FilterCrews(entities, q);
                int num = (source.Count<Crew>() + 9) / 10;
                num = (num == 0) ? 1 : num;
                QueryResult<Crew> result2 = new QueryResult<Crew>
                {
                    MaxRows = source.Count(),
                    Page = q.PageNumber,
                    Total = num
                };
                result2.Items = (from i in source
                                 orderby i.WorkStart
                                 select i)
                                 .Skip<Crew>(((q.PageNumber - 1) * q.PageSize))
                                 .Take<Crew>(q.PageSize).AsEnumerable<Crew>()
                                 .Select<Crew, Crew>(it => it.Clone()).ToArray<Crew>();
                return result2;
            }
        }

        public static CrewType GetCrewType(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.CrewTypes
                        where i.Id == id
                        select i).AsEnumerable<CrewType>()
                        .Select<CrewType, CrewType>(it => it.Clone()).FirstOrDefault<CrewType>();
            }
        }

        public static QueryResult<CrewType> GetCrewTypes(CrewTypeQuery q)
        {
            IList<CrewType> source = FilterCrewTypes(q);
            int num = (source.Count<CrewType>() + 9) / 10;
            num = (num == 0) ? 1 : num;
            QueryResult<CrewType> result = new QueryResult<CrewType>
            {
                MaxRows = source.Count(),
                Page = q.PageNumber,
                Total = num
            };

            result.Items = source.OrderBy<CrewType, int?>(it => it.Order)
                .Skip<CrewType>(((q.PageNumber - 1) * q.PageSize))
                .Take<CrewType>(q.PageSize)
                .Select<CrewType, CrewType>(it => it.Clone()).ToArray<CrewType>();
            return result;
        }

        public static Customer GetCustomer(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Customers
                        where i.Id == id
                        select i).AsEnumerable<Customer>()
                        .Select<Customer, Customer>(it => it.Clone()).FirstOrDefault<Customer>();
            }
        }

        public static QueryResult<Customer> GetCustomers(CustomerQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Customer> source = FilterCustomers(entities, q);
                int num = (source.Count<Customer>() + 9) / 10;
                num = (num == 0) ? 1 : num;
                QueryResult<Customer> result2 = new QueryResult<Customer>
                {
                    MaxRows = source.Count(),
                    Page = q.PageNumber,
                    Total = num
                };
                result2.Items = (from i in source
                                 orderby i.Id descending
                                 select i)
                                 .Skip<Customer>(((q.PageNumber - 1) * q.PageSize))
                                 .Take<Customer>(q.PageSize).AsEnumerable<Customer>()
                                 .Select<Customer, Customer>(it => it.Clone()).ToArray<Customer>();
                return result2;
            }
        }

        public static Order GetOrder(long id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Orders
                        where i.Id == id
                        select i).AsEnumerable<Order>()
                        .Select<Order, Order>(it => it.Clone()).FirstOrDefault<Order>();
            }
        }

        public static QueryResult<Order> GetOrders(OrderQuery q)
        {
            try
            {
                using (CarerEntities entities = new CarerEntities())
                {
                    IEnumerable<Order> source = FilterOrders(entities, q);
                    int num = (source.Count<Order>() + 9) / 10;
                    num = (num == 0) ? 1 : num;
                    QueryResult<Order> result2 = new QueryResult<Order>
                    {
                        MaxRows = source.Count(),
                        Page = q.PageNumber,
                        Total = num
                    };

                    result2.Items = source.OrderByDescending(it => it.CreateTime)
                            .ThenByDescending<Order, string>(it => it.Area)
                            .ThenByDescending<Order, DateTime?>(it => it.Start).ThenByDescending<Order, long>(it => it.Id)
                            .Skip<Order>(((q.PageNumber - 1) * q.PageSize))
                            .Take<Order>(q.PageSize)
                            .Select<Order, Order>((val) =>
                            {
                                if (val != null)
                                {
                                    return val.Clone();
                                }
                                return null;
                            }).ToArray<Order>();

                    return result2;
                }
            }
            catch (Exception ex)
            {
                _logger.Error("GetOrders报错：" + ex.Message + ex.StackTrace);
            }

            return null;
        }

        public static IList<Order> GetOrders(RevenueQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                var filterOrders = FilterOrders(entities, q);
                var result = (from i in filterOrders
                              let pay = i.Schedules.Sum<Schedule>(it => it.Pay)
                              let adjust = i.Schedules.Sum<Schedule>(it => it.Adjust)
                              select new Tuple<Order, double?, double?>(i, pay, adjust))
                        .Select(it =>
                        {
                            Order order = it.Item1.Clone();
                            order.Pay = it.Item2;
                            order.PayAdjust = it.Item3;
                            return order;
                        }).ToList();

                return result;
            }
        }
        public static QueryResult<Order> GetOrdersNew(RevenueQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                var filterOrders = FilterOrders(entities, q);
                int maxRows = filterOrders.Count();
                if (maxRows > 0)
                {
                    //int maxPageNumber = maxRows % q.PageSize == 0 ? maxRows / q.PageSize : maxRows / q.PageSize + 1;
                    //if (q.PageNumber > maxPageNumber)
                    //{
                    //    q.PageNumber = maxPageNumber;
                    //}

                    //QueryResult<Order> result = new QueryResult<Order>
                    //{
                    //    MaxRows = maxRows,
                    //    Page = q.PageNumber,
                    //    Total = maxRows % q.PageSize == 0 ? (maxRows / q.PageSize) : (maxRows / q.PageSize + 1),
                    //    Items = (from i in filterOrders
                    //             let pay = i.Schedules.Sum<Schedule>(it => it.Pay)
                    //             let adjust = i.Schedules.Sum<Schedule>(it => it.Adjust)
                    //             select new Tuple<Order, double?, double?>(i, pay, adjust))
                    //        .Skip<Tuple<Order, double?, double?>>(((q.PageNumber - 1) * q.PageSize))
                    //        .Take<Tuple<Order, double?, double?>>(q.PageSize).AsEnumerable<Tuple<Order, double?, double?>>()
                    //        .Select(it =>
                    //        {
                    //            Order order = it.Item1.Clone();
                    //            order.Pay = it.Item2;
                    //            order.PayAdjust = it.Item3;
                    //            return order;
                    //        }).ToList()
                    //};
                    //return result;

                    QueryResult<Order> result = new QueryResult<Order>
                    {
                        MaxRows = maxRows,
                        Page = 0,
                        Total = 0,
                        Items = (from i in filterOrders
                                 let pay = i.Schedules.Sum<Schedule>(it => it.Pay)
                                 let adjust = i.Schedules.Sum<Schedule>(it => it.Adjust)
                                 select new Tuple<Order, double?, double?>(i, pay, adjust))
                            .AsEnumerable<Tuple<Order, double?, double?>>()
                            .Select(it =>
                            {
                                Order order = it.Item1.Clone();
                                order.Pay = it.Item2;
                                order.PayAdjust = it.Item3;
                                return order;
                            }).ToList()
                    };
                    return result;
                }
                else
                {
                    return new QueryResult<Order>
                    {
                        MaxRows = 0,
                        Page = q.PageNumber,
                        Total = 0,
                        Items = new List<Order>()
                    };
                }
            }
        }

        public static Payment GetPayment(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Payments
                        where i.Id == id
                        select i).AsEnumerable<Payment>()
                        .Select<Payment, Payment>(it => it.Clone()).FirstOrDefault<Payment>();
            }
        }

        public static QueryResult<Payment> GetPayments(PaymentQuery q)
        {
            IList<Payment> source = FilterPayments(q);
            int num = (source.Count<Payment>() + 9) / 10;
            num = (num == 0) ? 1 : num;
            QueryResult<Payment> result = new QueryResult<Payment>
            {
                MaxRows = source.Count(),
                Page = q.PageNumber,
                Total = num
            };
            result.Items = source.OrderBy<Payment, int>(it => it.Id)
                .Skip<Payment>(((q.PageNumber - 1) * q.PageSize))
                .Take<Payment>(q.PageSize)
                .Select<Payment, Payment>(it => it.Clone()).ToArray<Payment>();
            return result;
        }

        public static Schedule GetSchedule(long id)
        {
            using (CarerEntities entities = new CarerEntities())
            {

                return (from i in entities.Schedules.Include("Crew").Include("Order.Service").Include("Order.Customer")
                        where i.Id == id
                        select i).AsEnumerable<Schedule>()
                        .Select<Schedule, Schedule>(it => it.Clone()).FirstOrDefault<Schedule>();
            }
        }
        public static QueryResult<Schedule> GetSchedulesNew(PayQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Schedule> source = FilterSchedules(entities, q).OrderBy(it => it.CrewId);
                int maxRows = source.Count();
                if (maxRows > 0)
                {
                    //int maxPageNumber = maxRows % q.PageSize == 0 ? maxRows / q.PageSize : maxRows / q.PageSize + 1;
                    //if (q.PageNumber > maxPageNumber)
                    //{
                    //    q.PageNumber = maxPageNumber;
                    //}

                    //QueryResult<Schedule> result = new QueryResult<Schedule>
                    //{
                    //    MaxRows = maxRows,
                    //    Page = q.PageNumber,
                    //    Total = maxRows % q.PageSize == 0 ? (maxRows / q.PageSize) : (maxRows / q.PageSize + 1),
                    //    Items = (from i in source
                    //             orderby i.CrewId, i.Start
                    //             select i)
                    //       .Skip<Schedule>(((q.PageNumber - 1) * q.PageSize))
                    //       .Take<Schedule>(q.PageSize).AsEnumerable<Schedule>()
                    //       .Select<Schedule, Schedule>(it => it.Clone()).ToArray<Schedule>()
                    //};
                    //return result;

                    QueryResult<Schedule> result = new QueryResult<Schedule>
                    {
                        MaxRows = maxRows,
                        Page = 0,
                        Total = 0,
                        Items = (from i in source
                                 orderby i.CrewId, i.Start
                                 select i)
                           .AsEnumerable<Schedule>()
                           .Select<Schedule, Schedule>(it => it.Clone()).ToArray<Schedule>()
                    };
                    return result;
                }
                else
                {
                    return new QueryResult<Schedule>
                    {
                        MaxRows = 0,
                        Page = q.PageNumber,
                        Total = 0,
                        Items = new List<Schedule>()
                    };
                }
            }
        }
        public static QueryGroup<Schedule> GetSchedules(PayQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<IGrouping<int?, Schedule>> source = from i in FilterSchedules(entities, q) group i by i.CrewId;
                int num = source.Count<IGrouping<int?, Schedule>>();
                num = (num == 0) ? 1 : num;
                IEnumerable<IGrouping<DateTime?, Schedule>> enumerable = (from g in
                                                                              (from i in source
                                                                               orderby i.Key
                                                                               select i).Skip<IGrouping<int?, Schedule>>((q.PageNumber - 1)).Take<IGrouping<int?, Schedule>>(1)
                                                                          select from i in g group i by DbFunctions.TruncateTime(i.Start)).FirstOrDefault<IEnumerable<IGrouping<DateTime?, Schedule>>>();
                QueryGroup<Schedule> group2 = new QueryGroup<Schedule>
                {
                    Page = q.PageNumber,
                    Total = num
                };
                if (enumerable != null)
                {
                    if (func_33 == null)
                    {
                        func_33 = new Func<IGrouping<DateTime?, Schedule>, Schedule[]>(DataService.smethod_36);
                    }
                    group2.Items = enumerable.Select<IGrouping<DateTime?, Schedule>, Schedule[]>(func_33).ToArray<Schedule[]>();
                }
                return group2;
            }
        }

        public static IList<Schedule> GetSchedulesAll(ScheduleQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Schedule> source = FilterSchedules(entities, q);
                return source.Select(it => it.Clone()).ToList();
            }
        }
        public static QueryResult<Schedule> GetSchedules(ScheduleQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Schedule> source = FilterSchedules(entities, q);
                int num = (source.Count<Schedule>() + 9) / 10;
                num = (num == 0) ? 1 : num;
                QueryResult<Schedule> result2 = new QueryResult<Schedule>
                {
                    MaxRows = source.Count(),
                    Page = q.PageNumber,
                    Total = num
                };
                result2.Items = (from i in source
                                 orderby i.Start descending, i.Start, i.CrewId
                                 select i)
                                 .Skip<Schedule>(((q.PageNumber - 1) * q.PageSize))
                                 .Take<Schedule>(q.PageSize).AsEnumerable<Schedule>()
                                 .Select<Schedule, Schedule>(it => it.Clone()).ToArray<Schedule>();
                return result2;
            }
        }

        public static List<Schedule> GetSchedulesAll(WorkQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                var source = FilterSchedules(entities, q);
                return source.Select<Schedule, Schedule>(it => it.Clone()).ToList();
            }
        }

        public static List<Schedule> GetSchedulesAll(PayQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                var source = FilterSchedules(entities, q);
                return source.Select<Schedule, Schedule>(it => it.Clone()).ToList();
            }
        }
        public static QueryResult<Schedule> GetSchedulesNew(WorkQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<Schedule> source = FilterSchedules(entities, q).OrderBy(it => it.CrewId).ThenBy(it => it.Start);
                int maxRows = source.Count();
                if (maxRows > 0)
                {
                    //int maxPageNumber = maxRows % q.PageSize == 0 ? maxRows / q.PageSize : maxRows / q.PageSize + 1;
                    //if (q.PageNumber > maxPageNumber)
                    //{
                    //    q.PageNumber = maxPageNumber;
                    //}
                    //QueryResult<Schedule> result = new QueryResult<Schedule>
                    // {
                    //     MaxRows = maxRows,
                    //     Page = q.PageNumber,
                    //     Total = maxRows % q.PageSize == 0 ? (maxRows / q.PageSize) : (maxRows / q.PageSize + 1),
                    //     Items = (from i in source
                    //              orderby i.CrewId, i.Start
                    //              select i)
                    //        .Skip<Schedule>(((q.PageNumber - 1) * q.PageSize))
                    //        .Take<Schedule>(q.PageSize).AsEnumerable<Schedule>()
                    //        .Select<Schedule, Schedule>(it => it.Clone()).ToArray<Schedule>()
                    // };
                    //return result;

                    QueryResult<Schedule> result = new QueryResult<Schedule>
                    {
                        MaxRows = maxRows,
                        Page = 0,
                        Total = 0,
                        Items = (from i in source
                                 orderby i.CrewId, i.Start
                                 select i)
                           .AsEnumerable<Schedule>()
                           .Select<Schedule, Schedule>(it => it.Clone()).ToArray<Schedule>()
                    };
                    return result;
                }
                else
                {
                    return new QueryResult<Schedule>
                    {
                        MaxRows = 0,
                        Page = q.PageNumber,
                        Total = 0,
                        Items = new List<Schedule>()
                    };
                }
            }
        }
        public static QueryGroup<Schedule> GetSchedules(WorkQuery q)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                IQueryable<IGrouping<int?, Schedule>> source = from i in FilterSchedules(entities, q) group i by i.CrewId;
                int num = source.Count<IGrouping<int?, Schedule>>();
                num = (num == 0) ? 1 : num;
                IEnumerable<IGrouping<DateTime?, Schedule>> enumerable = (from g in
                                                                              (from i in source
                                                                               orderby i.Key
                                                                               select i).Skip<IGrouping<int?, Schedule>>((q.PageNumber - 1)).Take<IGrouping<int?, Schedule>>(1)
                                                                          select from i in g group i by DbFunctions.TruncateTime(i.Start)).FirstOrDefault<IEnumerable<IGrouping<DateTime?, Schedule>>>();
                QueryGroup<Schedule> group2 = new QueryGroup<Schedule>
                {
                    Page = q.PageNumber,
                    Total = num
                };
                if (enumerable != null)
                {
                    if (func_31 == null)
                    {
                        func_31 = new Func<IGrouping<DateTime?, Schedule>, Schedule[]>(DataService.smethod_34);
                    }
                    group2.MaxRows = enumerable.Count();
                    group2.Items = enumerable.Select<IGrouping<DateTime?, Schedule>, Schedule[]>(func_31).ToArray<Schedule[]>();
                }
                return group2;
            }
        }

        public static Service GetService(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Services
                        where i.Id == id
                        select i).AsEnumerable<Service>().Select<Service, Service>(it => it.Clone()).FirstOrDefault<Service>();
            }
        }

        public static QueryResult<Service> GetServices(ServiceQuery q)
        {
            IList<Service> source = FilterServices(q);
            int num = (source.Count<Service>() + 9) / 10;
            num = (num == 0) ? 1 : num;
            QueryResult<Service> result = new QueryResult<Service>
            {
                MaxRows = source.Count(),
                Page = q.PageNumber,
                Total = num
            };

            result.Items = source.OrderBy<Service, int>(it => it.Id)
                .Skip<Service>(((q.PageNumber - 1) * q.PageSize))
                .Take<Service>(q.PageSize)
                .Select<Service, Service>(it => it.Clone()).ToArray<Service>();
            return result;
        }

        public static Unit GetUnit(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Units
                        where i.Id == id
                        select i).AsEnumerable<Unit>().Select<Unit, Unit>(it => it.Clone()).FirstOrDefault<Unit>();
            }
        }

        public static QueryResult<Unit> GetUnits(UnitQuery q)
        {
            IList<Unit> source = FilterUnits(q);
            int num = (source.Count<Unit>() + 9) / 10;
            num = (num == 0) ? 1 : num;
            QueryResult<Unit> result = new QueryResult<Unit>
            {
                MaxRows = source.Count(),
                Page = q.PageNumber,
                Total = num
            };
            result.Items = source.OrderBy<Unit, int?>(it => it.Order ?? 0)
                .Skip<Unit>(((q.PageNumber - 1) * q.PageSize))
                .Take<Unit>(q.PageSize).Select<Unit, Unit>(it => it.Clone()).ToArray<Unit>();
            return result;
        }

        public static User GetUser(int id)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Users.Include("Unit")
                        where i.Id == id
                        select i).AsEnumerable<User>().Select<User, User>(it => it.Clone()).FirstOrDefault<User>();
            }
        }

        public static User GetUser(string name)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                return (from i in entities.Users.Include("Unit")
                        where i.Name == name
                        select i).FirstOrDefault<User>();
            }
        }

        public static QueryResult<User> GetUsers(UserQuery q)
        {
            IList<User> source = FilterUsers(q);
            int num = (source.Count<User>() + 9) / 10;
            num = (num == 0) ? 1 : num;
            QueryResult<User> result = new QueryResult<User>
            {
                MaxRows = source.Count(),
                Page = q.PageNumber,
                Total = num
            };

            result.Items = source.OrderBy<User, int>(it => it.Id).Skip<User>(((q.PageNumber - 1) * q.PageSize))
                .Take<User>(q.PageSize)
                .Select<User, User>(it => it.Clone())
                .ToArray<User>();
            return result;
        }

        public static QueryResult<Wage> GetWagesNew(WageQuery q)
        {
            using (CarerEntities ctx = new CarerEntities())
            {
                var filterSchedules = FilterSchedules(ctx, q);
                var filterWages = (from i in filterSchedules
                                   group i by i.CrewId into g
                                   let crew = (from c in ctx.Crews
                                               where c.Id == g.Key
                                               select c).FirstOrDefault<Crew>()
                                   select new Wage
                                   {
                                       Id = crew.Id,
                                       Name = crew.Name,
                                       WorkStart = crew.WorkStart,
                                       CustomerCount = g.Select(f => f.Order.CustomerId).Distinct().Count(),
                                       Adjust = g.Sum(it => it.Adjust),
                                       Pay = g.Sum(it => it.Pay),
                                       DayCount = g.Where(f => f.CrewId == crew.Id).Select(f => DbFunctions.DiffHours(f.Start, f.End)).Sum(f => f ?? 0) / 24.0,
                                       Bonus = (from b in ctx.Bonuses
                                                where b.CrewId == crew.Id && (b.Date >= q.Start) && (b.Date <= q.End)
                                                select b).Sum(it => it.Value)
                                   });

                int maxRows = filterWages.Count();
                if (maxRows > 0)
                {
                    //int maxPageNumber = maxRows % q.PageSize == 0 ? maxRows / q.PageSize : maxRows / q.PageSize + 1;
                    //if (q.PageNumber > maxPageNumber)
                    //{
                    //    q.PageNumber = maxPageNumber;
                    //}

                    //QueryResult<Wage> result = new QueryResult<Wage>
                    //{
                    //    MaxRows = maxRows,
                    //    Page = q.PageNumber,
                    //    Total = maxRows % q.PageSize == 0 ? (maxRows / q.PageSize) : (maxRows / q.PageSize + 1),
                    //    Items = filterWages.OrderBy(it => it.WorkStart)
                    //             .Skip<Wage>(((q.PageNumber - 1) * q.PageSize))
                    //             .Take<Wage>(q.PageSize).ToList()
                    //};
                    //return result;                    

                    QueryResult<Wage> result = new QueryResult<Wage>
                    {
                        MaxRows = maxRows,
                        Page = q.PageNumber,
                        Total = 0,
                        Items = filterWages.OrderBy(it => it.WorkStart).ToList()
                    };

                    return result;
                }
                else
                {
                    return new QueryResult<Wage>
                    {
                        MaxRows = 0,
                        Page = q.PageNumber,
                        Total = 0,
                        Items = new List<Wage>()
                    };
                }
            }
        }

        public static IList<Wage> GetWages(WageQuery q)
        {
            using (CarerEntities ctx = new CarerEntities())
            {
                var filterSchedules = FilterSchedules(ctx, q);
                var result = (from i in filterSchedules
                              group i by i.CrewId into g
                              let crew = (from c in ctx.Crews
                                          where c.Id == g.Key
                                          select c).FirstOrDefault<Crew>()
                              select new Wage
                              {
                                  Id = crew.Id,
                                  Name = crew.Name,
                                  CustomerCount = g.Count<Schedule>(),
                                  Adjust = g.Sum(it => it.Adjust),
                                  Pay = g.Sum(it => it.Pay),
                                  DayCount = (from i in g group i by DbFunctions.TruncateTime(i.Start)).Count<IGrouping<DateTime?, Schedule>>(),
                                  Bonus = (from b in ctx.Bonuses
                                           where (b.Date > q.Start) && (b.Date < q.End)
                                           select b).Sum(it => it.Value)
                              }).ToList();

                return result;
            }
        }

        public static bool SaveChanges(CarerEntities ctx)
        {
            try
            {
                ctx.SaveChanges();
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }
        /// <summary>
        /// 校验排班信息
        /// </summary>
        /// <param name="schedule"></param>
        /// <param name="orderIds">新增时候的订单ids</param>
        /// <returns></returns>
        public static Tuple<bool, string> CheckSchedule(Schedule schedule, long[] orderIds)
        {
            using (CarerEntities ctx = new CarerEntities())
            {
                //0-全天,1-白班,2-夜班
                //一个客户也在同一天最多一个全班或者白班加夜班
                //TODO针对排班信息没有结束时间，以开始时间为准比较
                var startTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 8, 0, 0);
                if (schedule.Start.HasValue)
                {
                    startTime = schedule.Start.Value;
                }
                var endTime = startTime.AddDays(1);
                if (schedule.End.HasValue)
                {
                    endTime = schedule.End.Value;
                }

                if (schedule.Id == 0)
                {
                    #region 新增
                    int addCount = orderIds != null ? orderIds.Length : 1;
                    int limitCount = 3 + 1 - addCount;

                    var query = ctx.Schedules.Where(it => it.OrderId.HasValue && orderIds.Contains(it.OrderId.Value)
                        && ((it.End.HasValue && it.Start < endTime && it.End > startTime) || (!it.End.HasValue && it.Start > startTime && it.Start < endTime))).ToList();
                    if (query.Exists(it => it.Shift.HasValue && it.Shift.Value == 0) ||
                        query.Exists(it => it.Shift == schedule.Shift))
                    {
                        return new Tuple<bool, string>(false, "客户当前排班冲突");
                    }

                    #endregion
                }
                else
                {
                    #region 修改
                    var query = ctx.Schedules.Where(it => it.OrderId == schedule.OrderId && it.Id != schedule.Id
                        && ((it.End.HasValue && it.Start < endTime && it.End > startTime) || (!it.End.HasValue && it.Start > startTime && it.Start < endTime))).ToList();
                    if (query.Exists(it => it.Shift.HasValue && it.Shift.Value == 0) ||
                         query.Exists(it => it.Shift == schedule.Shift) || (schedule.Shift == 0 && query.Count > 0))
                    {
                        return new Tuple<bool, string>(false, "客户当前排班冲突");
                    }
                    #endregion
                }
            }

            return new Tuple<bool, string>(true, string.Empty);
        }
        /// <summary>
        /// 订单结账
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public static bool SettleOrders(long[] ids)
        {
            using (CarerEntities entities = new CarerEntities())
            {
                foreach (long id in ids)
                {
                    //订单完成:256 才能结账
                    //订单结账:257
                    Order entity = (from i in entities.Orders
                                    where i.Id == id && i.State == 256
                                    select i).FirstOrDefault<Order>();
                    if (entity != null)
                    {
                        entity.State = 257;
                    }
                }
                return SaveChanges(entities);
            }
        }
        private static Schedule[] smethod_34(IGrouping<DateTime?, Schedule> g)
        {
            return g.Select<Schedule, Schedule>(it => it.Clone()).ToArray<Schedule>();
        }

        private static Schedule[] smethod_36(IGrouping<DateTime?, Schedule> g)
        {
            if (func_34 == null)
            {
                func_34 = new Func<Schedule, Schedule>(DataService.smethod_37);
            }
            return g.Select<Schedule, Schedule>(func_34).ToArray<Schedule>();
        }


        private static Schedule smethod_37(Schedule schedule_0)
        {
            return schedule_0.Clone();
        }
    }
}

